
/**
  ******************************************************************************
  * Copyright 2021 The Microbee Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       internal_error.h
  * @author     baiyang
  * @date       2023-1-2
  ******************************************************************************
  */

#pragma once

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include <stdint.h>
/*-----------------------------------macro------------------------------------*/
#define INTERNAL_ERROR(error_number) \
    internal_error_set(error_number, __LINE__);
/*----------------------------------typedef-----------------------------------*/
// note that this map is an internal microbee fixture and is
// prone to change at regular intervals.  The meanings of these
// bits can change day-to-day.
enum internal_error_type {                           // Hex      Decimal
    internal_error_logger_mapfailure           = (1U <<  0),  // 0x00001  1
    internal_error_logger_missing_logstructure = (1U <<  1),  // 0x00002  2
    internal_error_logger_logwrite_missingfmt  = (1U <<  2),  // 0x00004  4
    internal_error_logger_too_many_deletions   = (1U <<  3),  // 0x00008  8
    internal_error_logger_bad_getfilename      = (1U <<  4),  // 0x00010  16
    internal_error_panic                       = (1U <<  5),  // 0x00020  32
    internal_error_logger_flushing_without_sem = (1U <<  6),  // 0x00040  64
    internal_error_logger_bad_current_block    = (1U <<  7),  // 0x00080  128
    internal_error_logger_blockcount_mismatch  = (1U <<  8),  // 0x00100  256
    internal_error_logger_dequeue_failure      = (1U <<  9),  // 0x00200  512
    internal_error_constraining_nan            = (1U << 10),  // 0x00400  1024
    internal_error_watchdog_reset              = (1U << 11),  // 0x00800  2048
    internal_error_iomcu_reset                 = (1U << 12),  // 0x01000  4096
    internal_error_iomcu_fail                  = (1U << 13),  // 0x02000  8192
    internal_error_spi_fail                    = (1U << 14),  // 0x04000  16384
    internal_error_main_loop_stuck             = (1U << 15),  // 0x08000  32768
    internal_error_gcs_bad_missionprotocol_link= (1U << 16),  // 0x10000  65536
    internal_error_bitmask_range               = (1U << 17),  // 0x20000  131072
    internal_error_gcs_offset                  = (1U << 18),  // 0x40000  262144
    internal_error_i2c_isr                     = (1U << 19),  // 0x80000  524288
    internal_error_flow_of_control             = (1U << 20),  //0x100000  1048576 for generic we-should-never-get-here situations
    internal_error_switch_full_sector_recursion= (1U << 21),  //0x200000  2097152
    internal_error_bad_rotation                = (1U << 22),  //0x400000  4194304
    internal_error_stack_overflow              = (1U << 23),  //0x800000  8388608
    internal_error_imu_reset                   = (1U << 24),  //0x1000000 16777216
    internal_error_gpio_isr                    = (1U << 25),  //0x2000000 33554432
    internal_error_mem_guard                   = (1U << 26),  //0x4000000 67108864
    internal_error_dma_fail                    = (1U << 27),  //0x8000000 134217728
    internal_error_params_restored             = (1U << 28),  //0x10000000 268435456
    internal_error_invalid_arg_or_result       = (1U << 29),  //0x20000000 536870912
    internal_error_storage_fail                = (1U << 30),  //0x40000000 1073741824
    internal_error___LAST__                    = (1U << 31),  // used only for sanity check
};

typedef struct internal_error* internal_error_t;
typedef const struct internal_error* internal_error_const_t;

struct internal_error {
    // bitmask holding errors from internal_error_t
    uint32_t internal_errors;

    uint32_t total_error_count;
    uint16_t last_line;
};
/*----------------------------------variable----------------------------------*/

/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
internal_error_const_t internal_error_get_singleton();
void internal_error_set(const enum internal_error_type e, uint16_t line);
void internal_error_to_string(char *buffer, const uint16_t len, enum internal_error_type error_code);
void internal_error_errors_as_string(uint8_t *buffer, const uint16_t len);
/*------------------------------------test------------------------------------*/

#ifdef __cplusplus
}
#endif



